package be.jabapage.snooker.service.importation.impl;

import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.Validate;

import be.jabapage.snooker.container.ClubContainer;
import be.jabapage.snooker.container.TeamContainer;
import be.jabapage.snooker.exception.EntityNotFoundException;
import be.jabapage.snooker.exception.MultipleInstanceFoundException;
import be.jabapage.snooker.exception.ProcessingException;
import be.jabapage.snooker.jdo.administration.Club;
import be.jabapage.snooker.jdo.administration.Player;
import be.jabapage.snooker.service.administration.api.IClubService;
import be.jabapage.snooker.service.importation.api.IClubImportService;
import be.jabapage.snooker.service.importation.api.IPlayerImportService;
import be.jabapage.snooker.service.importation.api.ITeamImportService;
import be.jabapage.snooker.service.overwriter.api.IClubOverwriter;

/**
 * @author axesq
 *
 */
public class ClubImportService implements IClubImportService, Serializable {

	private static final long serialVersionUID = 2866693979674352163L;
	private final IClubService clubService;
	private final IClubOverwriter clubOverwriter;
	private final ITeamImportService teamImportService;
	private final IPlayerImportService playerImportService;


	/**
	 * @param clubService
	 * @param clubOverwriter
	 * @param teamImportService
	 * @param playerImportService
	 */
	public ClubImportService(final IClubService clubService, final IClubOverwriter clubOverwriter, final ITeamImportService teamImportService, final IPlayerImportService playerImportService) {
		Validate.notNull(clubService);
		Validate.notNull(clubOverwriter);
		Validate.notNull(teamImportService);
		Validate.notNull(playerImportService);
		this.clubService = clubService;
		this.clubOverwriter = clubOverwriter;
		this.teamImportService = teamImportService;
		this.playerImportService = playerImportService;
	}

	/**
	 * {@inheritDoc}
	 */
	public void importClubs(final ClubContainer club) throws ProcessingException {
		Validate.notNull(club);
		Club clubItem = club.getClub();
		Validate.notNull(clubItem, "We cannot import a club if the club itself is null.");

		//searching the club
		try {
			Club clubDatabase = clubService.retrieve(clubItem.getName());
			clubOverwriter.overwrite(clubDatabase, clubItem);
			clubService.store(clubItem);
		} catch (MultipleInstanceFoundException e) {
			throw new ProcessingException("Multiple clubs found.", e);
		} catch (EntityNotFoundException e) {
			clubService.store(clubItem);
		}

		storeTeams(clubItem.getId(), club.getTeams());
		storeBackupPlayers(clubItem.getId(), club.getBackupPlayers());
	}

	private void storeBackupPlayers(final Long clubId, final Map<String, Player> backupPlayers) throws ProcessingException {
		Validate.notNull(clubId);
		Validate.notNull(backupPlayers);
		for (Entry<String, Player> player : backupPlayers.entrySet()) {
			player.getValue().setClubId(clubId);
			playerImportService.importPlayer(player.getValue());
		}
	}

	private void storeTeams(final Long clubId, final Map<String, TeamContainer> teams) throws ProcessingException {
		Validate.notNull(clubId);
		Validate.notNull(teams);
		for (Entry<String, TeamContainer> team : teams.entrySet()) {
			Validate.notNull(team.getValue());
			team.getValue().getTeam().setClubId(clubId);
			teamImportService.importTeam(team.getValue());
		}
	}


}
